package cz.vse.po1715.lode.net.server;

import cz.vse.po1715.lode.net.obecne.ISHrac;
import cz.vse.po1715.lode.net.obecne.Konstanty;
import cz.vse.po1715.lode.net.obecne.KonfiguraceHry;
import cz.vse.po1715.lode.net.obecne.IHerniUdalost;
import java.util.*;

/*******************************************************************************
 * Instance třídy {@code ASprávceHry} představují vzor pro logickou implementaci
 * správců her běžících na serveru.
 * Jsou potomkem třídy {@code ASprávceUdálostí} a poskytují fond pomocných
 * vláken a frontu příchozích událostí pro své potomky.
 *
 * @author    Dominik KOSTKA
 * @version   0.00.000
 */
public abstract class ASprávceHry extends ASprávceUdálostí
{
//== KONSTANTNÍ ATRIBUTY TŘÍDY =================================================
//== PROMĚNNÉ ATRIBUTY TŘÍDY ===================================================
//== STATICKÝ INICIALIZAČNÍ BLOK - STATICKÝ KONSTRUKTOR ========================
//== KONSTANTNÍ ATRIBUTY INSTANCÍ ==============================================
//== PROMĚNNÉ ATRIBUTY INSTANCÍ ================================================

    /** odkaz na spuštěný herní server */
    protected Server server;
//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ TŘÍDY ========================================
//== OSTATNÍ NESOUKROMÉ METODY TŘÍDY ===========================================

//##############################################################################
//== KONSTRUKTORY A TOVÁRNÍ METODY =============================================

    /***************************************************************************
     *
     */
    public ASprávceHry()
    {
    }



//== ABSTRAKTNÍ METODY =========================================================

    /**
     * Potomci třídy ASprávceHry by měly implementovat metodu initSpravceHry,
     * aby mohly provádět inicializaci, kterou požadují.
     */
    protected abstract void initSpravceHry(KonfiguraceHry konfigurace);

    /**
     * potomci musí implementovat, aby poskytovaly jméno hry
     */
    public abstract String getNazevHry();

    /**
     * Tovární metoda pro získání instance hráče
     */
    public abstract ISHrac vytvorHrac();

    /**
     * Tovární metoda pro získání instance herní události
     */
    public abstract IHerniUdalost vytvorHerniUdalost();

//== PŘÍSTUPOVÉ METODY VLASTNOSTÍ INSTANCÍ =====================================
//== OSTATNÍ NESOUKROMÉ METODY INSTANCÍ ========================================

    /**
     * Inicializuje na serveru Správce událostí a správce hry
     */
    public final void inicializuj(Server server, KonfiguraceHry konfigurace) {
	this.server = server;

	// todo: dostat preferovaný počet vláken od KonfiguraceHry
	//	int nw = konfigurace.getInt("NUM_WORKERS", 5);

	// nejprve inicializuje správce událostí
	initSprávceUdálostí(Konstanty.SPRÁVCE_HER_PRACOVNÍCI);
	// a následně sebe
	initSpravceHry(konfigurace);
    }

    /**
     * Metoda pro posílání události ze serveru zadanému hráči
     */
    protected void posliUdalost(IHerniUdalost událost, ISHrac hráč) {
	událost.setIdHráče(hráč.getIdHrac());
	server.předejUdálost(událost);
    }

    /**
     * Metoda pro posílání události ze serveru zadaným hráčům
     */
    protected synchronized void posliUdalostHromadne(IHerniUdalost událost, Collection hráči) {
	Iterator i = hráči.iterator();
	String[] příjemci = new String[hráči.size()];
	int j=0;
	while(i.hasNext()) {
	    ISHrac hráč = (ISHrac) i.next();
	    if (!(hráč.getIdHrac().equals(událost.getIdHrac())))
		příjemci[j++] = hráč.getIdHrac();
	}
	událost.setPříjemci(příjemci);

        //pomocí serveru předá událost zapisovači událostí
	server.předejUdálost(událost);
    }

//== SOUKROMÉ A POMOCNÉ METODY TŘÍDY ===========================================
//== SOUKROMÉ A POMOCNÉ METODY INSTANCÍ ========================================
//== INTERNÍ DATOVÉ TYPY =======================================================
//== TESTOVACÍ METODY A TŘÍDY ==================================================
//
//    /***************************************************************************
//     * Testovací metoda.
//     */
//    public static void test()
//    {
//        ASprávceHry inst = new ASprávceHry();
//    }
//    /** @param args Parametry příkazového řádku - nepoužívané. */
//    public static void main( String[] args )  {  test();  }
}
